package com.app.brilliant.sign.interceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.app.brilliant.language.util.MessageSourceUtil;
import com.app.brilliant.common.api.ApiResult;
import com.app.brilliant.sign.constant.ResponseCode;
import com.app.brilliant.sign.util.MD5Util;
import com.app.brilliant.sign.util.ResultUtil;
import com.app.brilliant.sign.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* interceptor for api sign
* 拦截器 依此判断是否拦截
*
*/

@Component
public class SignInterceptor implements HandlerInterceptor {
    private static final String SIGN_KEY = "apisign_";
    private static final String appSecret = "22c811b9c3e146c69bfee37d241380e0";
    @Autowired
    private MessageSourceUtil messageSourceUtil;
    /**
     * @description:
     * @param request：请求对象
     * @param response：响应对象
     * @param handler：处理对象：controller中的信息   *
     * *@return:true表示正常,false表示被拦截
    */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String timestampStr = request.getParameter("timestamp");
        if (StringUtils.isBlank(timestampStr)) {
            String message = messageSourceUtil.getMessage(ResponseCode.SIGN_NO_TIMESTAMP.getMsg(),"zh","timestamp 不能为空");
            ApiResult localResult = ApiResult.fail(message);
            ServletUtil.renderString(response, JSON.toJSONString(localResult));
            return false;
        }
        //getHeader 获取浏览器中的信息sign
        String sign = request.getParameter("sign");
        if (StringUtils.isBlank(sign)) {
            ServletUtil.renderString(response, JSON.toJSONString(ResultUtil.error(ResponseCode.SIGN_NO_SIGN)));
            return false;
        }
        String nonce = request.getParameter("nonce");
        if (StringUtils.isBlank(nonce)) {
            ServletUtil.renderString(response, JSON.toJSONString(ResultUtil.error(ResponseCode.SIGN_NO_NONCE)));
            return false;
        }
        ApiResult responseCode = handleCheckSign(request);
        if(!responseCode.isSuccess()){
            ServletUtil.renderString(response, JSON.toJSONString(responseCode));
            return false;
        }
        return true;
    }

    private ApiResult handleCheckSign(ServletRequest httpServletRequest){
        Map<String,String> map = getSignMap(httpServletRequest);
        String sign = map.get("sign");
        if(sign== null){
            return ApiResult.fail(ResponseCode.SIGN_NO_SIGN.getMsg());
        }
        map.remove("sign");
        String calcSign = MD5Util.getSign(map,appSecret);
        if(!calcSign.equals(sign)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("params",map);
            jsonObject.put("sign",sign);
            jsonObject.put("calcSign",calcSign);
            return ApiResult.fail(jsonObject.toJSONString());
        }
        return ApiResult.ok();
    }

    private Map<String,String> getSignMap(ServletRequest httpServletRequest){
        Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
        Map<String,String[]> maps = new HashMap<>(parameterMap);
        Map<String,String> map = com.app.brilliant.util.StringUtils.getMapFromParams(maps);
        return map;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}